// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
//
// $Id: attribute.cpp 318 2009-03-02 14:03:21Z heavyzheng $
//

#ifndef ZZHENG_XML_SOURCE
#define ZZHENG_XML_SOURCE
#endif // ZZHENG_XML_SOURCE

#include <zzheng/xml/dom/libxml2/attribute.hpp>
#include <zzheng/xml/dom/libxml2/utility.hpp>

#include <libxml/tree.h>
#include <cassert>
#include <string>

namespace zzheng {
namespace xml {
namespace dom {
namespace libxml2_ {

    attribute::attribute(xmlNode* px): node(px) {
        assert(raw()->type == XML_ATTRIBUTE_NODE);
    }

    attribute::~attribute() {
        // Do nothing.
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // property access
    //

    std::string attribute::uri() const {
        if (raw()->ns != 0 && raw()->ns->href != 0) {
            return to_chars(raw()->ns->href);
        } else {
            return std::string();
        }
    }

    std::string attribute::prefix() const {
        if (raw()->ns != 0 && raw()->ns->prefix != 0) {
            return to_chars(raw()->ns->prefix);
        } else {
            return std::string();
        }
    }

    std::string attribute::qname() const {
        std::string pre = prefix();
        if (pre.empty()) {
            return name();
        } else {
            return (pre + ":" + name());
        }
    }

    void attribute::set_name(const std::string& name) {
        // TODO: check if the name is a valid name.
        xmlNodeSetName(raw(), to_xml_chars(name.c_str()));
    }

    std::string attribute::value() const {
        return content();
    }

    void attribute::set_value(const std::string& value) {
        set_content(value);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // sibling access
    //

    basic_node_ptr<attribute> attribute::prev_sibling() {
        return basic_node_ptr<attribute>( const_cast<attribute*>(prev_sibling_()) );
    }

    basic_node_ptr<attribute> attribute::next_sibling() {
        return basic_node_ptr<attribute>( const_cast<attribute*>(next_sibling_()) );
    }

    basic_node_ptr<const attribute> attribute::prev_sibling() const {
        return basic_node_ptr<const attribute>( prev_sibling_() );
    }

    basic_node_ptr<const attribute> attribute::next_sibling() const {
        return basic_node_ptr<const attribute>( next_sibling_() );
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // private
    //

    const attribute* attribute::prev_sibling_() const {
        if (raw()->prev != 0) {
            return static_cast<const attribute*>(raw()->prev->_private);
        } else {
            return 0;
        }
    }

    const attribute* attribute::next_sibling_() const {
        if (raw()->next != 0) {
            return static_cast<const attribute*>(raw()->next->_private);
        } else {
            return 0;
        }
    }

    attribute* attribute::clone(bool recursive) const {
        xmlNode* px = clone_raw(recursive);
        return static_cast<attribute*>(px->_private);
    }

} // namespace zzheng::xml::dom::libxml2_
} // namespace zzheng::xml::dom
} // namespace zzheng::xml
} // namespace zzheng




